package com.howbuy.tools.beanchange;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import com.howbuy.base.ToolBase;

/**
 * javaBean生成类
 * @author boqi.feng
 *
 */
public class ChangeForBean {
	private static String path = "bean";
	private static String returnPath = "bean";
	// 不送的话默认为fileName的txt格式
	private static String returnFileName = "";
	//需要上送上送PO还是返回Po
	private static boolean isRequest=true;
	

	public static void main(String[] args) throws IOException {
		// 输入流
		File[] fileList = ToolBase.readFile(path, null);
			for(int i=0;i<fileList.length;i++){
				getBeanForDevelopment(fileList[i]);
			}
	}
	
	public static void getBeanForDevelopment(File file) throws IOException{
		if (file.length() == 0) {
			System.out.println("没有读到文件");
		}
		FileInputStream fis = new FileInputStream(file);
		@SuppressWarnings("resource")
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis,ToolBase.CHARSET));
		String line = null;
		String type = null;//数据类型
		String value = null;//字段名
		
		boolean isComments = false; //是否为备注
		
		StringBuffer  comments = new StringBuffer();//备注列表
		
		StringBuffer defineSf = new StringBuffer();//requestData字段值及备注
		StringBuffer valueSf = new StringBuffer();//requestData get/set及备注
		
		StringBuffer definePOsf = new StringBuffer();//bean字段值及备注
		StringBuffer valuePOsf = new StringBuffer(); //bean get/set及备注
		
		//按行处理文件
		while ((line = bufferedReader.readLine()) != null) {
			line = line.trim();
			if ("".equals(line)) {
				continue;
			}
			if (line.contains("static") || line.contains("final")) {
				System.out.println("有属性为static或者final，建议仔细检查");
				throw new IOException();
			}
			if (line.endsWith(";")) {
				line = line.substring(0, line.length() - 1);
			}
			// 获得注释内容
			if (line.startsWith("/**")&&line.endsWith("*/")) {
				comments.append("/**\r\n");
				comments.append(line.substring(3, line.length()-2));
				comments.append("\r\n*/");
			}else if (line.startsWith("/**")) {
				comments.append(line);
				isComments=true;
			} else if (line.startsWith("*")) {
				comments.append("\r\n");
				comments.append(line);
			}else if (line.startsWith("*/")) {
				comments.append("\r\n");
				comments.append(line);
				isComments = false;
			} else if (line.startsWith("private")) {//如果是private开头，说明是属性
				//根据入参写代码，并放入文件中
				String[] str = line.split(" ");
				type = str[1];
				value = str[2];
				String commentStr = comments.toString();
				commentStr = commentStr.replace("/***", "/**");
				
				convertForPo(value,commentStr,type,definePOsf,valuePOsf);
				//RequestData不增加disCode和termType
				if(!checkValue(value)&&isRequest){
					continue;
				}
				convertForModel(value, commentStr, type, defineSf, valueSf);
				
				comments = new StringBuffer();
			}else if(isComments){
				comments.append("\r\n");
				comments.append(line);
				if(line.contains("*/")){
					isComments = false;
				}
			} 
		}
		bufferedReader.close();
		
		defineSf.append(valueSf);

		writeLRequestFile(defineSf,file.getName());

		definePOsf.append(valuePOsf);
		writeBeansFile(definePOsf,file.getName());
	}
	
	/**
	 * 根据文件内容获取PO
	 * @param value
	 * @param comments
	 * @param type
	 * @param definePOsf
	 * @param valuePOsf
	 */
	private static void convertForPo(String value, String comments,
			String type, StringBuffer definePOsf, StringBuffer valuePOsf) {
		// 增加注释并换行
		definePOsf.append(comments);
		definePOsf.append("\r\n");
		// 定义变量
		definePOsf.append("private " + type +" " + value+";");
		
		definePOsf.append("\r\n");
		
		// 方法内参数首字母改大写
		String methodName = value.substring(0, 1).toUpperCase()
				+ value.substring(1, value.length());
		
		// 增加注释并换行
		valuePOsf.append(comments);
		valuePOsf.append("\r\n");
		// 生成get方法
		valuePOsf.append("public " + type + " get" + methodName + "(){");
		valuePOsf.append("\r\n");
		valuePOsf.append("return "+ value+";\r\n}");
		valuePOsf.append("\r\n");

		// 增加注释并换行
		valuePOsf.append(comments);
		valuePOsf.append("\r\n");
		// 生成set方法
		valuePOsf.append("public void set" + methodName + "(" + type + " "
				+ value + "){");
		valuePOsf.append("\r\n");
		valuePOsf.append("this." + value + "=" + value + ";\r\n}");
		valuePOsf.append("\r\n");
	}

	private static void writeBeansFile(StringBuffer returnValue, String fileName)  throws IOException{
		StringBuffer printValue= new StringBuffer();
		String[] str = fileName.split("\\.");
		if(isRequest){
			fileName= str[0]+ "Po";
		}else{
			fileName= str[0]+ "RetPo";
		}
		printValue.append("public class " + fileName + "{");
		printValue.append("\r\n");
		printValue.append(returnValue);
		printValue.append("}");
		createFile(fileName + ".java",printValue);
		System.out.println("------Pay层"+fileName+"文件生成完毕");
		
		if(isRequest){
			fileName=str[0]+ "ChannelPo";
		}else{
			fileName=str[0]+ "ChannelRetPo";
		}
		printValue= new StringBuffer();
		printValue.append("public class " + fileName + "{");
		printValue.append("\r\n");
		printValue.append(returnValue);
		printValue.append("}");
		createFile(fileName + ".java",printValue);
		System.out.println("------Channel层"+fileName+"文件生成完毕");
		
		if(isRequest){
			fileName=str[0]+ "BankPo";
		}else{
			fileName=str[0]+ "BankRetPo";
		}
		printValue= new StringBuffer();
		printValue.append("public class " + fileName + "{");
		printValue.append("\r\n");
		printValue.append(returnValue);
		printValue.append("}");
		createFile(fileName + ".java",printValue);
		System.out.println("------Bank层"+fileName+"文件生成完毕");
	}

	private static boolean checkValue(String value) throws IOException{
		boolean flag;
		if(isRequest){
			flag=true;
		}else if("disCode".equals(value)||"termType".equals(value)){
			flag=false;
		}else{
			flag=true;
		}
		return flag;
	}

	/** 将生成的内容存入指定文件  
	 * @param string */
	private static void writeLRequestFile(StringBuffer returnValue, String fileName) throws  IOException {
		// 输出流
		if ("".equals(returnFileName.trim())) {
			String[] str = fileName.split("\\.");
			if(isRequest){
				fileName = str[0]+ "RequestData";
			}else{
				fileName = str[0]+ "Response";
			}
			
			
		}
		StringBuffer printValue= new StringBuffer();
		printValue.append("public class " + fileName + "{");
		printValue.append("\r\n");
		printValue.append(returnValue);
		printValue.append("}");
		printValue.append("\r\n");
		createFile(fileName + ".java",printValue);
		System.out.println("------Action层"+fileName+"文件生成完毕");
	}

	private static void createFile(String returnFileName,StringBuffer returnValue) throws IOException {
		File returnFile = ToolBase.getWriteFile(returnPath, returnFileName);
		FileOutputStream fos = new FileOutputStream(returnFile);
		OutputStreamWriter osw = new OutputStreamWriter(fos, ToolBase.CHARSET);
		int buff = 200;
		for(int i=0;i<returnValue.length();i+=buff){
			char[] buffer = new char[buff];
			int strEnd = i + buff;
			if(strEnd>returnValue.length()){
				strEnd=returnValue.length();
			}
			returnValue.getChars(i, strEnd, buffer, 0);
			osw.write(buffer);
		}
		osw.write(buff);
		osw.flush();
		fos.close();
		osw.close();
	}

	/**
	 * 根据入参、字段类型和注释来生成文件
	 * 
	 * @param line
	 * @param comments
	 * @param type
	 * @param valueSf
	 * @param defineSf
	 * @throws IOException
	 */
	private static void convertForModel(String value, String comments,
			String type, StringBuffer defineSf, StringBuffer valueSf)
			throws IOException {
		// 增加注释并换行
		defineSf.append(comments);
		defineSf.append("\r\n");
		// 定义变量
		defineSf.append("private static final String " + value.toUpperCase()
				+ " = \"" + value + "\";");
		defineSf.append("\r\n");
		// 方法内参数首字母改大写
		String methodName = value.substring(0, 1).toUpperCase()
				+ value.substring(1, value.length());

		// 增加注释并换行
		valueSf.append(comments);
		valueSf.append("\r\n");
		// 生成get方法
		valueSf.append("public " + type + " get" + methodName + "(){");
		valueSf.append("\r\n");
		valueSf.append("return getValue(" + value.toUpperCase() + "," + type
				+ ".class);\r\n}");
		valueSf.append("\r\n");

		// 增加注释并换行
		valueSf.append(comments);
		valueSf.append("\r\n");
		// 生成set方法
		valueSf.append("public void set" + methodName + "(" + type + " "
				+ value + "){");
		valueSf.append("\r\n");
		valueSf.append("setValue(" + value.toUpperCase() + "," + value
				+ ");\r\n}");
		valueSf.append("\r\n");

	}

}
